﻿#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using StarFox.ScreenComponents;
#endregion

namespace StarFox.Inputs
{
    /// <summary>
    /// Provides functionality needed for menu and gameplay player input management.
    /// </summary>
    public partial class StarFoxInput : IShipInput
    {
        #region Properties

        /// <summary>
        /// Gets or sets the threshold for thumbstick press detection in associated starship input actions.
        /// </summary>
        public float ShipThreshold { get; set; }

        #endregion

        #region Pitch-Axis

        /// <summary>
        /// Checks for a "rotate up around pitch axis" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsPitchUp(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.S, false);
            bool gamepad = input.IsThumbStickPress(Buttons.LeftThumbstickDown, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        /// <summary>
        /// Checks for a "rotate down around pitch axis" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsPitchDown(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.W, false);
            bool gamepad = input.IsThumbStickPress(Buttons.LeftThumbstickUp, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        #endregion

        #region Yaw-Axis

        /// <summary>
        /// Checks for a "rotate left around yaw axis" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsYawLeft(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.A, false);
            bool gamepad = input.IsThumbStickPress(Buttons.LeftThumbstickLeft, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        /// <summary>
        /// Checks for a "rotate right around yaw axis" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsYawRight(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.D, false);
            bool gamepad = input.IsThumbStickPress(Buttons.LeftThumbstickRight, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        #endregion

        #region Roll-Axis

        /// <summary>
        /// Checks for a "rotate left around roll axis" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsRollLeft(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.Q, false);
            bool gamepad = input.IsButtonPress(Buttons.LeftShoulder, playerIndex, false);

            return keyboard || gamepad;
        }

        /// <summary>
        /// Checks for a "rotate right around roll axis" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsRollRight(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.E, false);
            bool gamepad = input.IsButtonPress(Buttons.RightShoulder, playerIndex, false);

            return keyboard || gamepad;
        }

        #endregion

        #region Move Up/Down

        /// <summary>
        /// Checks for a "move up" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsMoveUp(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.Up, false);
            bool gamepad = input.IsThumbStickPress(Buttons.RightThumbstickUp, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        /// <summary>
        /// Checks for a "move down" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsMoveDown(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.Down, false);
            bool gamepad = input.IsThumbStickPress(Buttons.RightThumbstickDown, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        #endregion

        #region Move Right/Left

        /// <summary>
        /// Checks for a "move right" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsMoveRight(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.Right, false);
            bool gamepad = input.IsThumbStickPress(Buttons.RightThumbstickRight, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        /// <summary>
        /// Checks for a "move left" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsMoveLeft(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.Left, false);
            bool gamepad = input.IsThumbStickPress(Buttons.RightThumbstickLeft, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        #endregion

        #region Boost/Brake
        
        /// <summary>
        /// Checks for a "boost" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsBoost(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.Space, false);
            bool gamepad = input.IsTriggerPress(Buttons.RightTrigger, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        /// <summary>
        /// Checks for a "brake" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsBrake(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.RightShift, false);
            bool gamepad = input.IsTriggerPress(Buttons.LeftTrigger, playerIndex, ShipThreshold, false);

            return keyboard || gamepad;
        }

        #endregion

        #region Bomb

        /// <summary>
        /// Checks for a "bomb" input action.
        /// </summary>
        /// <param name="playerIndex">Specifies which player to read input from.</param>
        /// <returns>Input action performed.</returns>
        public bool IsBomb(PlayerIndex playerIndex)
        {
            bool keyboard = input.IsKeyPress(Keys.B, false);
            bool gamepad = input.IsButtonPress(Buttons.B, playerIndex, true);

            return keyboard || gamepad;
        }

        #endregion

        #region Testing
#if DEBUG
        /// <summary>
        /// Resets starship rotation.
        /// </summary>
        /// <returns>Input action performed.</returns>
        public bool IsResetShipRotation()
        {
            return input.IsKeyPress(Keys.T, true);
        }

        /// <summary>
        /// Resets starship translation.
        /// </summary>
        /// <returns>Input action performed.</returns>
        public bool IsResetShipTranslation()
        {
            return input.IsKeyPress(Keys.T, true);
        }
#endif
        #endregion
    }
}
